// fix Function.apply
if (!Function.apply) Function.prototype.apply = function(thisArg, argArray) {
	// Create a function reference to the calling object
	thisArg.____apply = this;
	// Build a string that will later execute the function 
	var fnApplyString = "thisArg.____apply(";
	
	// Check that the argArray are according to standards. Must be array...
	if (typeof(argArray) == "object" && typeof(argArray.length) != "undefined") {
		var quote, comma;
		for(i = 0; i < argArray.length; i++){
			// Add quotes only for string values
			quote = typeof(argArray[i]) == "string" ? "\"" : "";
			// add a comma as param-separator for all except the last param
			comma = (i+1) < argArray.length ? "," : "";
			// add the param to the string we are building
			fnApplyString += quote + argArray[i] + quote + comma;
		}
	} else if (typeof(argArray) != "undefined") {
		// argArray is not an array, but it is defined, so we notify that the 
		// argArray must be an array when specified (according to ECMAScript specs)
		throw TypeError;
	}
	
	fnApplyString += ")";
	// eval the expression, now using the right object, function and parameters
	var retVal = eval(fnApplyString);
	// clean up our expando property reference
	delete thisArg.____apply;
	// return the value that the function was to return
	return retVal;
};

// fix array methods - I believe I borrowed this from Dean Edwards's IE7 script - same license ;-)
if (![].push) Array.prototype.push = function() {
	for(var i=0; i<arguments.length; i++)
		this[this.length-1] = arguments[i];
	return this.length;
};


if (![].pop) Array.prototype.pop = function() {
	var $item = this[this.length-1];
	this.length--;
	return $item;
};

if (![].shift) Array.prototype.shift = function () {
	return this.splice(0, 1)[0];
};

if (![].splice) Array.prototype.splice = function (s, d) {
	var max = Math.max,
		min = Math.min,
		a = [], // The return value array
		e,  // element
		i = max(arguments.length - 2, 0),   // insert count
		k = 0,
		l = this.length,
		n,  // new length
		v,  // delta
		x;  // shift count

	s = s || 0;
	if (s < 0) {
		s += l;
	}
	s = max(min(s, l), 0);  // start point
	d = max(min(isNumber(d) ? d : l, l - s), 0);    // delete count
	v = i - d;
	n = l + v;
	while (k < d) {
		e = this[s + k];
		if (!isUndefined(e)) {
			a[k] = e;
		}
		k += 1;
	}
	x = l - s - d;
	if (v < 0) {
		k = s + i;
		while (x) {
			this[k] = this[k - v];
			k += 1;
			x -= 1;
		}
		this.length = n;
	} else if (v > 0) {
		k = 1;
		while (x) {
			this[n - k] = this[l - k];
			k += 1;
			x -= 1;
		}
	}
	for (k = 0; k < i; ++k) {
		this[s + k] = arguments[k + 2];
	}
	return a;
};

if (![].unshift) Array.prototype.unshift = function () {
	this.splice.apply(this,
		[0, 0].concat(Array.prototype.slice.apply(arguments)));
	return this.length;
};
